package page;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Vladimir Dudnic, Derek Fleener, Michael Groenier
 * PageAnalyzer class analyzes the collected pages content
 */
public class PageAnalyzer implements Runnable
{
       
        private PageParser parser;
       
        private boolean cont;
       
        /** 
         * Map of keywords and their count.
         */
        Map<String, Integer> keyword_count;
       
        /** 
         * Set of keywords to keep track of. 
         */
        List<String> keywords;
       
        /** 
         * Count of pages retrieved. 
         */
        int page_count;
       
        /**
         *  Count of all words.
         */
        int word_count;
       
        /** 
         * Count of URLs. 
         */
        int URL_count;
        
      
        /**
         * Constructor that initializes with everything
         * empty and values set to 0.
         */
        public PageAnalyzer(PageParser parser) 
        {
                this.parser = parser;
                cont = true;
                keyword_count = new HashMap<String, Integer>();
                keywords = new ArrayList<String>();
                page_count = 0;
                word_count = 0;
                URL_count = 0;
        }
       
        /**
         * Adds the given word to the set of keywords.
         *
         * @param keyword The word to be added.
         */
        public void addKeyword(String keyword)
        {
                keywords.add(keyword);
                keyword_count.put(keyword, 0);
        }
       
        /**
         * Increases the count for each keyword that
         * is found within the given list.
         *
         * @param text The text to search through.
         */
        public void findKeywords(List<String> text)
        {
                String keyword;
                for (int i = 0; i < text.size(); i++)
                {
                        if (keywords.contains(text.get(i)))
                        {
                                keyword = text.get(i);
                                keyword_count.put(keyword, keyword_count.get(keyword) + 1);
                        }
                }
                word_count = word_count + text.size();
                page_count++;
        }
       
       
        /**
         * @return the list of keywords.
         */
        public List<String> getKeywords()
        {
                return keywords;
        }
       
        /**
         * @return the total number of pages crawled.
         */
        public int getPagesRetrieved() 
        {
                return page_count;
        }
       
        /**
         * @return the average amount of words per page.
         */
        public int getAvgWords() 
        {
                if (page_count != 0)
                {
                        return word_count / page_count;
                }
                return 0;
        }
       
        /**
         * @return the average amount of URLs per page.
         */
        public int getAvgURLs() 
        {
                if (page_count != 0)
                {
                        return parser.getParsed() / page_count;
                }
                return 0;
        }

       
        /**
         * @param keyword The keyword to count.
         * @return the total hits a keyword has.
         */
        public int getTotalHits(String keyword)
        {
                return keyword_count.get(keyword);
        }
        
        public static double Round(double number, int decimals)
        {
        	double mod = Math.pow(10.0, decimals);
        	return Math.round(number * mod ) / mod;
        }
        
        /**
         * @param keyword The keyword to count.
         * @return the average hits per page a keyword has.
         */
        public double getAvgHits(String keyword) 
        {
                if(page_count != 0)
                {
                        return Round((double) keyword_count.get(keyword) / (double) page_count, 2);
                }
                return 0;
        }
       /**
        * Calculates the average parse time per page.
        * @return The average parse time per page.
        */
        public double getAvgParseTime() 
        {
                return (double) parser.getParseTime() / parser.getParseCount();
        }

        private void analyze() throws InterruptedException 
        {
                if (parser.checkParsedPages() > 0)
                {
                        List<String> toSearch = parser.getParsedPage();
                        findKeywords(toSearch);
                }
        }
       /**
        * Halts the search.
        */
        public void forceQuit() 
        {
                cont = false;
        }
       /**
        * The main method used to run this program. 
        * (implements runnable interface)
        */
        @Override
        public void run()
        {
                while (cont) 
                {
                        try 
                        {
                                analyze();
                        }
                        catch (InterruptedException e) 
                        {
                                cont = false;
                        }
                       
                }
               
        }
}

